home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / OutOfPhase1.01Source / OutOfPhase Folder / ImportAIFFSample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  21.9 KB  |  668 lines  |  [TEXT/KAHL]

  1. /* ImportAIFFSample.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ImportAIFFSample.h"
  31. #include "Memory.h"
  32. #include "MainWindowStuff.h"
  33. #include "Files.h"
  34. #include "Alert.h"
  35. #include "BufferedFileInput.h"
  36. #include "SampleConsts.h"
  37. #include "DataMunging.h"
  38. #include "SampleObject.h"
  39.  
  40.  
  41. /* prototype for the function that actually does the work. */
  42. static MyBoolean        TryToImportAIFFFile(BufferedInputRec* File, NumBitsType* NumBitsOut,
  43.                                             NumChannelsType* NumChannelsOut, char** RawDataPtrOut,
  44.                                             long* NumSampleFramesOut, long* SamplingRateOut);
  45.  
  46.  
  47. /* this routine asks for a file and tries to import the contents of that */
  48. /* file as an AIFF sample.  it reports any errors to the user. */
  49. void                                ImportAIFFSample(struct MainWindowRec* MainWindow)
  50.     {
  51.         FileSpec*                    WhereIsTheFile;
  52.  
  53.         CheckPtrExistence(MainWindow);
  54.         WhereIsTheFile = GetFileAny();
  55.         if (WhereIsTheFile != NIL)
  56.             {
  57.                 FileType*                    FileDesc;
  58.  
  59.                 if (OpenFile(WhereIsTheFile,&FileDesc,eReadOnly))
  60.                     {
  61.                         BufferedInputRec*        File;
  62.  
  63.                         File = NewBufferedInput(FileDesc);
  64.                         if (File != NIL)
  65.                             {
  66.                                 NumBitsType        NumBits;
  67.                                 NumChannelsType    NumChannels;
  68.                                 char*                    SampleData;
  69.                                 long                    NumFrames;
  70.                                 long                    SamplingRate;
  71.  
  72.                                 if (TryToImportAIFFFile(File,&NumBits,&NumChannels,
  73.                                     &SampleData,&NumFrames,&SamplingRate))
  74.                                     {
  75.                                         SampleObjectRec*        ReturnedSampleObject;
  76.  
  77.                                         ReturnedSampleObject = MainWindowCopyRawSampleAndOpen(MainWindow,
  78.                                             SampleData,NumBits,NumChannels,0,0,0,0,0,0,0,SamplingRate,
  79.                                             261.625565300598635);
  80.                                         if (ReturnedSampleObject != NIL)
  81.                                             {
  82.                                                 char*                    Filename;
  83.  
  84.                                                 Filename = ExtractFileName(WhereIsTheFile);
  85.                                                 if (Filename != NIL)
  86.                                                     {
  87.                                                         /* we don't need to release the name */
  88.                                                         SampleObjectNewName(ReturnedSampleObject,Filename);
  89.                                                     }
  90.                                             }
  91.                                         ReleasePtr(SampleData);
  92.                                     }
  93.                                 EndBufferedInput(File);
  94.                             }
  95.                          else
  96.                             {
  97.                                 AlertHalt("There is not enough memory available to import the file.",NIL);
  98.                             }
  99.                         CloseFile(FileDesc);
  100.                     }
  101.                  else
  102.                     {
  103.                         AlertHalt("Unable to open the file for reading.",NIL);
  104.                     }
  105.                 DisposeFileSpec(WhereIsTheFile);
  106.             }
  107.     }
  108.  
  109.  
  110. /* AIFF/AIFF-C File Format: */
  111. /*     "FORM" */
  112. /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
  113. /*     4-byte type */
  114. /*        "AIFF" = AIFF format file */
  115. /*        "AIFC" = AIFF-C format file */
  116. /* in any order, these chunks can occur: */
  117. /*   Version Chunk (this only occurs in AIFF-C files) */
  118. /*     "FVER" */
  119. /*     4-byte big endian length, which should always be the value 4 (four) */
  120. /*     4-byte date code.  this is probably 0xA2805140 (stored big endian), but it */
  121. /*          probably doesn't matter. */
  122. /*   Common Chunk for AIFF files */
  123. /*     "COMM" */
  124. /*     4-byte big endian length. */
  125. /*        always 18 for AIFF files */
  126. /*     2-byte big endian number of channels */
  127. /*     4-byte big endian number of sample frames */
  128. /*     2-byte big endian number of bits per sample */
  129. /*        a value in the domain 1..32 */
  130. /*     10-byte extended precision number of frames per second */
  131. /*   Common Chunk for AIFF-C files */
  132. /*     "COMM" */
  133. /*     4-byte big endian length. */
  134. /*        22 + compression method string length for AIFF-C files */
  135. /*     2-byte big endian number of channels */
  136. /*     4-byte big endian number of sample frames */
  137. /*     2-byte big endian number of bits per sample */
  138. /*        a value in the domain 1..32 */
  139. /*     10-byte extended precision number of frames per second */
  140. /*     4-byte character code ID for the compression method */
  141. /*        "NONE" means there is no compression method used */
  142. /*     some characters in a string identifying the compression method */
  143. /*        this must be padded to an even number of bytes, but the pad is */
  144. /*        NOT included in the length descriptor for the chunk. */
  145. /*        for uncompressed data, the string should be */
  146. /*        "\x0enot compressed\x00", including the null, for 16 bytes. */
  147. /*        the total chunk length is thus 38 bytes. */
  148. /*   Sound Data Chunk */
  149. /*     "SSND" */
  150. /*     4-byte big endian number of bytes in sample data array */
  151. /*     4-byte big endian offset to the first byte of sample data in the array */
  152. /*     4-byte big endian number of bytes to which the sound data is aligned. */
  153. /*     any length vector of raw sound data. */
  154. /*        this must be padded to an even number of bytes, but the pad is */
  155. /*        NOT included in the length descriptor for the chunk. */
  156. /*        Samples are stored in an integral number of bytes, the smallest that */
  157. /*        is required for the specified number of bits.  If this is not an even */
  158. /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
  159. /*        Multichannel sound is interleaved with the left channel first. */
  160. static MyBoolean        TryToImportAIFFFile(BufferedInputRec* File, NumBitsType* NumBitsOut,
  161.                                             NumChannelsType* NumChannelsOut, char** RawDataPtrOut,
  162.                                             long* NumSampleFramesOut, long* SamplingRateOut)
  163.     {
  164.         char                            CharBuff[4];
  165.         MyBoolean                    IsAnAIFFCFile;
  166.         long                            FormChunkLength;
  167.         void*                            RawDataFromFile;
  168.         MyBoolean                    RawDataFromFileIsValid = False;
  169.         NumBitsType                NumBits;
  170.         MyBoolean                    NumBitsIsValid = False;
  171.         NumChannelsType        NumChannels;
  172.         MyBoolean                    NumChannelsIsValid = False;
  173.         long                            SamplingRate;
  174.         MyBoolean                    SamplingRateIsValid = False;
  175.         unsigned long            NumSampleFrames;
  176.         MyBoolean                    NumSampleFramesIsValid = False;
  177.  
  178.         CheckPtrExistence(File);
  179.  
  180.         /*     "FORM" */
  181.         if (!ReadBufferedInput(File,4,CharBuff))
  182.             {
  183.              DiskErrorPoint1:
  184.                 AlertHalt("Unable to read data from the file.",NIL);
  185.              ExitTheProcedureErrorPoint:
  186.                 if (RawDataFromFileIsValid)
  187.                     {
  188.                         ReleasePtr((char*)RawDataFromFile);
  189.                     }
  190.                 return False;
  191.             }
  192.         if (!MemEqu(CharBuff,"FORM",4))
  193.             {
  194.              BadFilePoint1:
  195.                 AlertHalt("The file is not an AIFF or AIFF-C file.",NIL);
  196.                 goto ExitTheProcedureErrorPoint;
  197.             }
  198.  
  199.         /*     4-byte big endian form chunk length descriptor (minus 8 for "FORM" & this) */
  200.         if (!ReadBufferedUnsignedLongBigEndian(File,(unsigned long*)&FormChunkLength))
  201.             {
  202.                 goto DiskErrorPoint1;
  203.             }
  204.  
  205.         /*     4-byte type */
  206.         /*        "AIFF" = AIFF format file */
  207.         /*        "AIFC" = AIFF-C format file */
  208.         if (!ReadBufferedInput(File,4,CharBuff))
  209.             {
  210.                 goto DiskErrorPoint1;
  211.             }
  212.         if (MemEqu(CharBuff,"AIFF",4))
  213.             {
  214.                 IsAnAIFFCFile = False;
  215.             }
  216.         else if (MemEqu(CharBuff,"AIFC",4))
  217.             {
  218.                 IsAnAIFFCFile = True;
  219.             }
  220.         else
  221.             {
  222.              UnknownAIFFFilePoint:
  223.                 AlertHalt("The file is not a variant of AIFF or AIFF-C file that I can deal with.",NIL);
  224.                 goto ExitTheProcedureErrorPoint;
  225.             }
  226.         FormChunkLength -= 4;
  227.  
  228.         /* now, read in chunks until we die */
  229.         while (FormChunkLength > 0)
  230.             {
  231.                 long                        LocalChunkLength;
  232.  
  233.                 /* get the chunk type */
  234.                 if (!ReadBufferedInput(File,4,CharBuff))
  235.                     {
  236.                         goto DiskErrorPoint1;
  237.                     }
  238.                 /* get the chunk length */
  239.                 if (!ReadBufferedUnsignedLongBigEndian(File,(unsigned long*)&LocalChunkLength))
  240.                     {
  241.                         goto DiskErrorPoint1;
  242.                     }
  243.                 FormChunkLength -= 8;
  244.                 /* adjust for even alignment */
  245.                 if ((LocalChunkLength % 2) != 0)
  246.                     {
  247.                         LocalChunkLength += 1;
  248.                     }
  249.                 FormChunkLength -= LocalChunkLength;
  250.  
  251.                 /* decode the chunk */
  252.                 if (MemEqu(CharBuff,"COMM",4))
  253.                     {
  254.                         unsigned long            Exponent;
  255.                         unsigned long            Mantissa;
  256.                         char                            StupidExtendedThang[10];
  257.  
  258.                         if (!IsAnAIFFCFile)
  259.                             {
  260.                                 unsigned short        ShortInteger;
  261.  
  262.                                 /*   Common Chunk for AIFF files */
  263.                                 /*     "COMM" */
  264.                                 /*     4-byte big endian length. */
  265.                                 /*        always 18 for AIFF files */
  266.                                 if (LocalChunkLength != 18)
  267.                                     {
  268.                                         goto UnknownAIFFFilePoint;
  269.                                     }
  270.  
  271.                                 /*     2-byte big endian number of channels */
  272.                                 if (!ReadBufferedUnsignedShortBigEndian(File,&ShortInteger))
  273.                                     {
  274.                                         goto DiskErrorPoint1;
  275.                                     }
  276.                                 switch (ShortInteger)
  277.                                     {
  278.                                         default:
  279.                                             goto UnknownAIFFFilePoint;
  280.                                         case 1:
  281.                                             NumChannels = eSampleMono;
  282.                                             NumChannelsIsValid = True;
  283.                                             break;
  284.                                         case 2:
  285.                                             NumChannels = eSampleStereo;
  286.                                             NumChannelsIsValid = True;
  287.                                             break;
  288.                                     }
  289.  
  290.                                 /*     4-byte big endian number of sample frames */
  291.                                 if (!ReadBufferedUnsignedLongBigEndian(File,&NumSampleFrames))
  292.                                     {
  293.                                         goto DiskErrorPoint1;
  294.                                     }
  295.                                 NumSampleFramesIsValid = True;
  296.  
  297.                                 /*     2-byte big endian number of bits per sample */
  298.                                 /*        a value in the domain 1..32 */
  299.                                 if (!ReadBufferedUnsignedShortBigEndian(File,&ShortInteger))
  300.                                     {
  301.                                         goto DiskErrorPoint1;
  302.                                     }
  303.                                 switch (ShortInteger)
  304.                                     {
  305.                                         default:
  306.                                             goto UnknownAIFFFilePoint;
  307.                                         case 1: case 2: case 3: case 4:
  308.                                         case 5: case 6: case 7: case 8:
  309.                                             NumBits = eSample8bit;
  310.                                             NumBitsIsValid = True;
  311.                                             break;
  312.                                         case 9: case 10: case 11: case 12:
  313.                                         case 13: case 14: case 15: case 16:
  314.                                             NumBits = eSample16bit;
  315.                                             NumBitsIsValid = True;
  316.                                             break;
  317.                                     }
  318.  
  319.                                 /*     10-byte extended precision number of frames per second */
  320.                                 if (!ReadBufferedInput(File,10,StupidExtendedThang))
  321.                                     {
  322.                                         goto DiskErrorPoint1;
  323.                                     }
  324.                             }
  325.                          else
  326.                             {
  327.                                 unsigned short        ShortInteger;
  328.                                 long                            Dumper;
  329.  
  330.                                 /*   Common Chunk for AIFF-C files */
  331.                                 /*     "COMM" */
  332.                                 /*     4-byte big endian length. */
  333.                                 /*        always 18 for AIFF files */
  334.                                 if (LocalChunkLength < 22)
  335.                                     {
  336.                                         goto UnknownAIFFFilePoint;
  337.                                     }
  338.  
  339.                                 /*     2-byte big endian number of channels */
  340.                                 if (!ReadBufferedUnsignedShortBigEndian(File,&ShortInteger))
  341.                                     {
  342.                                         goto DiskErrorPoint1;
  343.                                     }
  344.                                 switch (ShortInteger)
  345.                                     {
  346.                                         default:
  347.                                             goto UnknownAIFFFilePoint;
  348.                                         case 1:
  349.                                             NumChannels = eSampleMono;
  350.                                             NumChannelsIsValid = True;
  351.                                             break;
  352.                                         case 2:
  353.                                             NumChannels = eSampleStereo;
  354.                                             NumChannelsIsValid = True;
  355.                                             break;
  356.                                     }
  357.  
  358.                                 /*     4-byte big endian number of sample frames */
  359.                                 if (!ReadBufferedUnsignedLongBigEndian(File,&NumSampleFrames))
  360.                                     {
  361.                                         goto DiskErrorPoint1;
  362.                                     }
  363.                                 NumSampleFramesIsValid = True;
  364.  
  365.                                 /*     2-byte big endian number of bits per sample */
  366.                                 /*        a value in the domain 1..32 */
  367.                                 if (!ReadBufferedUnsignedShortBigEndian(File,&ShortInteger))
  368.                                     {
  369.                                         goto DiskErrorPoint1;
  370.                                     }
  371.                                 switch (ShortInteger)
  372.                                     {
  373.                                         default:
  374.                                             goto UnknownAIFFFilePoint;
  375.                                         case 1: case 2: case 3: case 4:
  376.                                         case 5: case 6: case 7: case 8:
  377.                                             NumBits = eSample8bit;
  378.                                             NumBitsIsValid = True;
  379.                                             break;
  380.                                         case 9: case 10: case 11: case 12:
  381.                                         case 13: case 14: case 15: case 16:
  382.                                             NumBits = eSample16bit;
  383.                                             NumBitsIsValid = True;
  384.                                             break;
  385.                                     }
  386.  
  387.                                 /*     10-byte extended precision number of frames per second */
  388.                                 if (!ReadBufferedInput(File,10,StupidExtendedThang))
  389.                                     {
  390.                                         goto DiskErrorPoint1;
  391.                                     }
  392.  
  393.                                 /*     4-byte character code ID for the compression method */
  394.                                 /*        "NONE" means there is no compression method used */
  395.                                 if (!ReadBufferedInput(File,4,CharBuff))
  396.                                     {
  397.                                         goto DiskErrorPoint1;
  398.                                     }
  399.                                 if (!MemEqu(CharBuff,"NONE",4))
  400.                                     {
  401.                                         goto UnknownAIFFFilePoint;
  402.                                     }
  403.  
  404.                                 /*     some characters in a string identifying the compression method */
  405.                                 /*        this must be padded to an even number of bytes, but the pad is */
  406.                                 /*        NOT included in the length descriptor for the chunk. */
  407.                                 /*        for uncompressed data, the string should be */
  408.                                 /*        "\x0enot compressed\x00", including the null, for 16 bytes. */
  409.                                 /*        the total chunk length is thus 38 bytes. */
  410.                                 for (Dumper = 0; Dumper < LocalChunkLength - 22; Dumper += 1)
  411.                                     {
  412.                                         unsigned char            Stupid;
  413.  
  414.                                         if (!ReadBufferedUnsignedChar(File,&Stupid))
  415.                                             {
  416.                                                 goto DiskErrorPoint1;
  417.                                             }
  418.                                     }
  419.                             }
  420.  
  421.                         /* extended 22050 = 400D AC44000000000000 */
  422.                         /* extended 22051 = 400D AC46000000000000 */
  423.                         /* extended 44100 = 400E AC44000000000000 */
  424.                         /* extended 44101 = 400E AC45000000000000 */
  425.                         Exponent = (((long)StupidExtendedThang[0] & 0xff) << 8)
  426.                             | ((long)StupidExtendedThang[1] & 0xff);
  427.                         Mantissa = (((long)StupidExtendedThang[2] & 0xff) << 24)
  428.                             | (((long)StupidExtendedThang[3] & 0xff) << 16)
  429.                             | (((long)StupidExtendedThang[4] & 0xff) << 8)
  430.                             | ((long)StupidExtendedThang[5] & 0xff);
  431.                         SamplingRate = (Mantissa >> (0x401e - Exponent));
  432.                         if (SamplingRate < MINSAMPLINGRATE)
  433.                             {
  434.                                 SamplingRate = MINSAMPLINGRATE;
  435.                             }
  436.                         if (SamplingRate > MAXSAMPLINGRATE)
  437.                             {
  438.                                 SamplingRate = MAXSAMPLINGRATE;
  439.                             }
  440.                         SamplingRateIsValid = True;
  441.                     }
  442.                 else if (MemEqu(CharBuff,"SSND",4))
  443.                     {
  444.                         unsigned long            AlignmentFactor;
  445.                         unsigned long            OffsetToFirstByte;
  446.  
  447.                         /*   Sound Data Chunk */
  448.                         /*     "SSND" */
  449.                         /*     4-byte big endian number of bytes in sample data array */
  450.  
  451.                         /* only one of these is allowed */
  452.                         if (RawDataFromFileIsValid)
  453.                             {
  454.                                 goto UnknownAIFFFilePoint;
  455.                             }
  456.  
  457.                         /*     4-byte big endian offset to the first byte of sample data in the array */
  458.                         if (!ReadBufferedUnsignedLongBigEndian(File,&OffsetToFirstByte))
  459.                             {
  460.                                 goto DiskErrorPoint1;
  461.                             }
  462.                         if (OffsetToFirstByte != 0)
  463.                             {
  464.                                 goto UnknownAIFFFilePoint;
  465.                             }
  466.  
  467.                         /*     4-byte big endian number of bytes to which the sound data is aligned. */
  468.                         if (!ReadBufferedUnsignedLongBigEndian(File,&AlignmentFactor))
  469.                             {
  470.                                 goto DiskErrorPoint1;
  471.                             }
  472.                         if (AlignmentFactor != 0)
  473.                             {
  474.                                 goto UnknownAIFFFilePoint;
  475.                             }
  476.  
  477.                         /*     any length vector of raw sound data. */
  478.                         /*        this must be padded to an even number of bytes, but the pad is */
  479.                         /*        NOT included in the length descriptor for the chunk. */
  480.                         /*        Samples are stored in an integral number of bytes, the smallest that */
  481.                         /*        is required for the specified number of bits.  If this is not an even */
  482.                         /*        multiple of 8, then the data is shifted left and the low bits are zeroed */
  483.                         /*        Multichannel sound is interleaved with the left channel first. */
  484.                         RawDataFromFile = AllocPtrCanFail(LocalChunkLength - 8,
  485.                             "TryToImportAIFFFile:  RawDataBuffer");
  486.                         if (RawDataFromFile == NIL)
  487.                             {
  488.                              NotEnoughMemoryPoint:
  489.                                 AlertHalt("There is not enough memory available to import the sample.",NIL);
  490.                                 goto ExitTheProcedureErrorPoint;
  491.                             }
  492.                         RawDataFromFileIsValid = True;
  493.                         if (!ReadBufferedInput(File,LocalChunkLength - 8,(char*)RawDataFromFile))
  494.                             {
  495.                                 goto DiskErrorPoint1;
  496.                             }
  497.                     }
  498.                 else
  499.                     {
  500.                         /* just read the data & get rid of it */
  501.                         while (LocalChunkLength > 0)
  502.                             {
  503.                                 unsigned char            Stupid;
  504.  
  505.                                 if (!ReadBufferedUnsignedChar(File,&Stupid))
  506.                                     {
  507.                                         goto DiskErrorPoint1;
  508.                                     }
  509.                                 LocalChunkLength -= 1;
  510.                             }
  511.                     }
  512.             }
  513.  
  514.         /* now, deal with the stuff we just got */
  515.         if (!RawDataFromFileIsValid || !NumBitsIsValid || !NumChannelsIsValid
  516.             || !SamplingRateIsValid || !NumSampleFramesIsValid)
  517.             {
  518.                 goto UnknownAIFFFilePoint;
  519.             }
  520.  
  521.         switch (NumChannels)
  522.             {
  523.                 default:
  524.                     EXECUTE(PRERR(ForceAbort,"ImportAIFFSample:  bad NumChannels"));
  525.                     break;
  526.                 case eSampleMono:
  527.                     switch (NumBits)
  528.                         {
  529.                             default:
  530.                                 EXECUTE(PRERR(ForceAbort,"ImportAIFFSample:  bad NumBits"));
  531.                                 break;
  532.                             case eSample8bit:
  533.                                 {
  534.                                     long                        Scan;
  535.                                     long                        ActualLimit;
  536.                                     char*                        SampleVector;
  537.  
  538.                                     SampleVector = AllocPtrCanFail(sizeof(char) * NumSampleFrames,
  539.                                         "ImportAIFFSample:  finished vector");
  540.                                     ActualLimit = PtrSize((char*)RawDataFromFile);
  541.                                     for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  542.                                         {
  543.                                             PRNGCHK(SampleVector,&(SampleVector[Scan]),
  544.                                                 sizeof(SampleVector[Scan]));
  545.                                             if (Scan * sizeof(char) < ActualLimit)
  546.                                                 {
  547.                                                     PRNGCHK(RawDataFromFile,&(((signed char*)RawDataFromFile)[Scan]),
  548.                                                         sizeof(((signed char*)RawDataFromFile)[Scan]));
  549.                                                     SampleVector[Scan] = ((signed char*)RawDataFromFile)[Scan];
  550.                                                 }
  551.                                              else
  552.                                                 {
  553.                                                     SampleVector[Scan] = 0;
  554.                                                 }
  555.                                         }
  556.                                     *RawDataPtrOut = (char*)SampleVector;
  557.                                 }
  558.                                 break;
  559.                             case eSample16bit:
  560.                                 {
  561.                                     long                        Scan;
  562.                                     long                        ActualLimit;
  563.                                     short*                    SampleVector;
  564.  
  565.                                     SampleVector = (short*)AllocPtrCanFail(sizeof(short) * NumSampleFrames,
  566.                                         "ImportAIFFSample:  finished vector");
  567.                                     ActualLimit = PtrSize((char*)RawDataFromFile) / 2;
  568.                                     for (Scan = 0; Scan < NumSampleFrames; Scan += 1)
  569.                                         {
  570.                                             PRNGCHK(SampleVector,&(SampleVector[Scan]),
  571.                                                 sizeof(SampleVector[Scan]));
  572.                                             if (Scan * sizeof(char) < ActualLimit)
  573.                                                 {
  574.                                                     PRNGCHK(RawDataFromFile,&(((short*)RawDataFromFile)[Scan * 2 + 1]),
  575.                                                         sizeof(((char*)RawDataFromFile)[Scan * 2 + 1]));
  576.                                                     SampleVector[Scan]
  577.                                                         = (((short)((signed char*)RawDataFromFile)[2
  578.                                                         * Scan] & 0xff) << 8) | (((char*)RawDataFromFile)[2
  579.                                                         * Scan + 1] & 0xff);
  580.                                                 }
  581.                                              else
  582.                                                 {
  583.                                                     SampleVector[Scan] = 0;
  584.                                                 }
  585.                                         }
  586.                                     *RawDataPtrOut = (char*)SampleVector;
  587.                                 }
  588.                                 break;
  589.                         }
  590.                     break;
  591.                 case eSampleStereo:
  592.                     switch (NumBits)
  593.                         {
  594.                             default:
  595.                                 EXECUTE(PRERR(ForceAbort,"ImportAIFFSample:  bad NumBits"));
  596.                                 break;
  597.                             case eSample8bit:
  598.                                 {
  599.                                     long                        Scan;
  600.                                     long                        ActualLimit;
  601.                                     char*                        SampleVector;
  602.  
  603.                                     SampleVector = AllocPtrCanFail(sizeof(char) * NumSampleFrames * 2,
  604.                                         "ImportAIFFSample:  finished vector");
  605.                                     ActualLimit = PtrSize((char*)RawDataFromFile);
  606.                                     for (Scan = 0; Scan < NumSampleFrames * 2; Scan += 1)
  607.                                         {
  608.                                             PRNGCHK(SampleVector,&(SampleVector[Scan]),
  609.                                                 sizeof(SampleVector[Scan]));
  610.                                             if (Scan * sizeof(char) < ActualLimit)
  611.                                                 {
  612.                                                     PRNGCHK(RawDataFromFile,&(((signed char*)RawDataFromFile)[Scan]),
  613.                                                         sizeof(((signed char*)RawDataFromFile)[Scan]));
  614.                                                     SampleVector[Scan] = ((signed char*)RawDataFromFile)[Scan];
  615.                                                 }
  616.                                              else
  617.                                                 {
  618.                                                     SampleVector[Scan] = 0;
  619.                                                 }
  620.                                         }
  621.                                     *RawDataPtrOut = (char*)SampleVector;
  622.                                 }
  623.                                 break;
  624.                             case eSample16bit:
  625.                                 {
  626.                                     long                        Scan;
  627.                                     long                        ActualLimit;
  628.                                     short*                    SampleVector;
  629.  
  630.                                     SampleVector = (short*)AllocPtrCanFail(sizeof(short) * 2
  631.                                         * NumSampleFrames,"ImportAIFFSample:  finished vector");
  632.                                     ActualLimit = PtrSize((char*)RawDataFromFile) / 2;
  633.                                     for (Scan = 0; Scan < NumSampleFrames * 2; Scan += 1)
  634.                                         {
  635.                                             PRNGCHK(SampleVector,&(SampleVector[Scan]),
  636.                                                 sizeof(SampleVector[Scan]));
  637.                                             if (Scan * sizeof(char) < ActualLimit)
  638.                                                 {
  639.                                                     PRNGCHK(RawDataFromFile,&(((char*)RawDataFromFile)[Scan * 2
  640.                                                         + 1]),sizeof(((char*)RawDataFromFile)[Scan * 2 + 1]));
  641.                                                     SampleVector[Scan]
  642.                                                         = (((short)((signed char*)RawDataFromFile)[2
  643.                                                         * Scan] & 0xff) << 8) | (((char*)RawDataFromFile)[2
  644.                                                         * Scan + 1] & 0xff);
  645.                                                 }
  646.                                              else
  647.                                                 {
  648.                                                     SampleVector[Scan] = 0;
  649.                                                 }
  650.                                         }
  651.                                     *RawDataPtrOut = (char*)SampleVector;
  652.                                 }
  653.                                 break;
  654.                         }
  655.                     break;
  656.             }
  657.  
  658.         ReleasePtr((char*)RawDataFromFile);
  659.  
  660.         *NumBitsOut = NumBits;
  661.         *NumChannelsOut = NumChannels;
  662.         CheckPtrExistence(*RawDataPtrOut);
  663.         *NumSampleFramesOut = NumSampleFrames;
  664.         *SamplingRateOut = SamplingRate;
  665.  
  666.         return True;
  667.     }
  668.